/*------------------------------------------------------------------------
*
* geqo_ox1.c
*
*	 顺序交叉 [OX] 例程；
*	 根据 Davis 的 OX1 运算符
*	 (国际人工智能联合会议论文集)
*
* src/backend/optimizer/geqo/geqo_ox1.c
*
*-------------------------------------------------------------------------
*/

/* 贡献者：
   =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
   *  Martin Utesch				 * 自动控制研究所		   *
   =							 = 矿业与技术大学 =
   *  utesch@aut.tu-freiberg.de  * 德国弗赖贝格				   *
   =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
 */

/* ox 算法是从 Genitor 采用的： */
/*************************************************************/
/*															 */
/*	Copyright (c) 1990										 */
/*	Darrell L. Whitley										 */
/*	计算机科学系									         */
/*	科罗拉多州立大学									     */
/*															 */
/*	特此允许复制本程序的全部或部分以进行自由分发。作者的姓名  */
/*	及本版权声明必须包含在任何复制中。 */
/* geqo_copy
 *
 *	 将一个基因复制到另一个
 *
 */
/*															 */
/*************************************************************/

#include "postgres.h"
#include "optimizer/geqo_random.h"
#include "optimizer/geqo_recombination.h"

#if defined(OX1)

/* ox1
 *
 *	 位置交叉
 */
void ox1(PlannerInfo *fc_root, Gene *fc_tour1, Gene *fc_tour2, Gene *fc_offspring, int fc_num_gene,
	City * fc_city_table)
{
	int			fc_left,
				fc_right,
				fc_k,
				fc_p,
				fc_temp;

	/* 初始化城市表 */
	for (fc_k = 1; fc_k <= fc_num_gene; fc_k++)
		fc_city_table[fc_k].used = 0;

	/* 从 tour1 选择要复制的部分 */
	fc_left = geqo_randint(fc_root, fc_num_gene - 1, 0);
	fc_right = geqo_randint(fc_root, fc_num_gene - 1, 0);

	if (fc_left > fc_right)
	{
		fc_temp = fc_left;
		fc_left = fc_right;
		fc_right = fc_temp;
	}

	/* 从 tour1 复制部分到后代 */
	for (fc_k = fc_left; fc_k <= fc_right; fc_k++)
	{
		fc_offspring[fc_k] = fc_tour1[fc_k];
		fc_city_table[(int) fc_tour1[fc_k]].used = 1;
	}

	fc_k = (fc_right + 1) % fc_num_gene; /* 后代中的索引 */
	fc_p = fc_k;						/* tour2 中的索引 */

	/* 从 tour2 复制内容到后代 */
	while (fc_k != fc_left)
	{
		if (!fc_city_table[(int) fc_tour2[fc_p]].used)
		{
			fc_offspring[fc_k] = fc_tour2[fc_p];
			fc_k = (fc_k + 1) % fc_num_gene;
			fc_city_table[(int) fc_tour2[fc_p]].used = 1;
		}
		fc_p = (fc_p + 1) % fc_num_gene; /* 增加 tour2 索引 */
	}
}

#endif							/* 定义（OX1） */
